package server.proxy.db;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import server.proxy.Config;
import server.proxy.TripleDES;


/**
 * This class stores the black list in the memory
 * @author Maxim
 *
 */
public class BlackList {

    private final ReentrantReadWriteLock _rwl;
    private final Lock _r;
    private final Lock _w;
    
    private ArrayList<String> _blackList;
    
    
    public BlackList() throws InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, FileNotFoundException, IOException{
    	
		this._rwl = new ReentrantReadWriteLock();
		this._r = this._rwl.readLock();
		this._w = this._rwl.writeLock();
		this._blackList = loadBlackList();
    }
    
    /**
     * This method inserts host to the black list
     * @param clientIP
     */
    public void insertHost(String hostName){
    	
		 this._w.lock(); 
		 try { 
			 this._blackList.add(hostName);
		 } 
		 finally { this._w.unlock(); }
    	
    }
    
    /**
     * This method removes host from the black list
     * @param clientIP
     */
    public void deleteHost(String hostName){
    	
		 this._w.lock(); 
		 try { 
			 this._blackList.remove(hostName);
		 } 
		 finally { this._w.unlock(); }
    	
    }
    
    
    public boolean isMemmber(String clientIP){
		 
    	this._r.lock(); 
		 try { 
			 return this._blackList.indexOf(clientIP) > -1;
		 } 
		 finally { this._r.unlock(); }
    	
    }
    
    
    public String toString(){
    	String tAnswer = "";
    	
    	int tBlackListSize = this._blackList.size();
    	
    	for(int j = 0 ; j < tBlackListSize; j++){
    		
    		if(j != tBlackListSize-1)
    			tAnswer+= this._blackList.get(j) + "\n";
    		else
    			tAnswer+= this._blackList.get(j);
    	}
    	
    	
    	return tAnswer;
    }
    
    
    
    
    
    
    /**
     * Loads the white list from white list file
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws BadPaddingException
     * @throws InvalidKeySpecException
     * @throws FileNotFoundException
     * @throws IOException
     */
    private ArrayList<String> loadBlackList() throws InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeySpecException, FileNotFoundException, IOException{
    	
    	ArrayList<String> tAnswer = new ArrayList<String>();
    	
		 ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
		 TripleDES.decrypt(TripleDES.readKey(new File(Config.PASSWORD_FILE_NAME)), new FileInputStream(Config.BLACK_LIST_FILE_NAME), out);
		 
		 String[] tRecords = out.toString().split("\n");
		 int tRecordSize = tRecords.length;
		 
		 for(int j = 0; j < tRecordSize; j++){
			 tAnswer.add(tRecords[j]);
		 }
    	
    	return tAnswer;
    }
    
    
    
    
    
    
    
    
    
	
	
}
